package games.chasingdodo;

import java.util.LinkedList;

public class GameStateChasingDodo {

	/**
	 * Score constants
	 */
	public static final int MAX_LIFE = 35;
	private static final int EGG_DAMAGE = 8;
	
	/**
	 * Static values
	 */
	private static int myScore;
	private static int enemyScore;

	/**
	 * Listeners of this class
	 */
	private LinkedList<OnGameStateUpdateListener> listeners;

	/**
	 * Values for thread
	 */
	public boolean playing;
	private boolean isControlingState;
	private static final int UPDATE_TIME = 500;

	/**
	 * Game state
	 */
	private int life = MAX_LIFE;
	private int corn;
	private int gameRound;
	private boolean gameEnabled;

	/**
	 * Attributes to test the connection
	 */
	private int controlMessage;
	private long lastUpdateTime;

	/**
	 * Connection
	 */
	private RoomManagerDodoGame roomManager;

	public GameStateChasingDodo(RoomManagerDodoGame roomManager, boolean isControlingState, int gameRound) {
		this.gameRound = gameRound;
		this.isControlingState = isControlingState;
		this.roomManager = roomManager;
		this.listeners = new LinkedList<OnGameStateUpdateListener>();
		startUdateThread();
	}

	public void startGameIn(final int seconds) {
		if(!playing) {
			playing = true;
			gameEnabled = true;
			new Thread(new Runnable() {

				@Override
				public void run() {
					try {Thread.sleep(seconds*1000);} catch (InterruptedException e) {}
					startUdateThread();
					gameEnabled = true;
					for (OnGameStateUpdateListener listener : listeners)
						listener.onBeginGame(isControlingState);
				}
			}).start();
		}
	}

	public void stopGame() {
		gameEnabled = false;
		playing = false;
	}

	public void disconnection() {
		stopGame();
		for (OnGameStateUpdateListener listener : listeners)
			listener.onGameStopedByOther();
	}

	public void disconnectGame() {
		new Thread(new Runnable() {

			@Override
			public void run() {
				for (int i = 0; i < 10; i++) {
					try {Thread.sleep(UPDATE_TIME);} catch (InterruptedException e) {}
					roomManager.sendDisconnectAlert();
				}
			}
		}).start();
	}

	public void startUdateThread() {

		new Thread(new Runnable() {

			@Override
			public void run() {
				while(playing) {
					if(gameEnabled && life == 0) {
						gameEnabled = false;
						if(isControlingState)
							myScore = corn;
						else
							enemyScore = corn;
						switch (gameRound) {
						case 0:
							for (OnGameStateUpdateListener listener : listeners)
								listener.onChangePlayingMode(isControlingState, corn);
							break;
						case 1:
							for (OnGameStateUpdateListener listener : listeners)
								listener.onFinishGame(isControlingState, myScore, enemyScore);
							break;
						}
					}
					if(isControlingState) {
						lastUpdateTime = System.currentTimeMillis();
						roomManager.sendGameState(controlMessage++, life, corn);
					} else {

					}
					try {Thread.sleep(UPDATE_TIME);} catch (InterruptedException e) {}
				}
			}
		}).start();

	}

	private void stepForwardInGame() {
		for (OnGameStateUpdateListener listener : listeners)
			listener.onChangePlayingMode(isControlingState, corn);
	}

	public boolean isGameEnabled() {
		return gameEnabled;
	}

	public void onNewControlMessage(int control, int life, int corn) {
		if(isControlingState) {

		} else {
			this.life = life;
			this.corn = corn;
			for (OnGameStateUpdateListener listener : listeners) {
				listener.onLifeChanged(life);
				listener.onCornChanged(corn);
			}
		}
	}

	public void addListener(OnGameStateUpdateListener listener) {
		this.listeners.add(listener);
		listener.onLifeChanged(life);
		listener.onCornChanged(corn);
	}

	public void increaseCorn() {
		if(gameEnabled) {
			corn ++;
			boolean lifeChanged = life < MAX_LIFE;
			if(lifeChanged)
				life ++;
			for (OnGameStateUpdateListener listener : listeners) {
				if(lifeChanged)
					listener.onLifeChanged(life);
				listener.onCornChanged(corn);
			}
		}
	}

	public void eggCrash() {
		if(gameEnabled) {
			if(life > EGG_DAMAGE)
				life -= EGG_DAMAGE;
			else
				life = 0;
			for (OnGameStateUpdateListener listener : listeners)
				listener.onLifeChanged(life);
		}
	}

	// ********************************* PAUSE-RESUME GAME *********************************

	// Not implemented yet
	public void requestPause() {}
	public void requestResume() {}

	// ********************************* PAUSE-RESUME GAME *********************************

	public interface OnGameStateUpdateListener {
		public void onLifeChanged(int life);
		public void onCornChanged(int corn);
		public void onBeginGame(boolean gameMode);
		public void onChangePlayingMode(boolean gameMode, int corn);
		public void onFinishGame(boolean gameMode, int myScore, int enemyScore);
		public void onReplay(boolean gameMode);
		public void onLostConnection();
		public void onGameStopedByOther();
	}

}
